package de.laures.cewolf.cpp;

import java.awt.Color;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.CombinedDomainCategoryPlot;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.CombinedRangeCategoryPlot;
import org.jfree.chart.plot.CombinedRangeXYPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.SpiderWebPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;

import de.laures.cewolf.ChartPostProcessor;
import de.laures.cewolf.jfree.WaferMapPlot;
import de.laures.cewolf.jfree.WaferMapRenderer;

/**
* A postprocessor for setting alternative colors for pie charts, category plots, XY plots and spider web plots.
* It takes numbered parameters containing the hex color values.
* <P>
* Usage:<P>
* &lt;chart:chartpostprocessor id="seriesPaint"&gt;<BR>
* &nbsp;&nbsp;&lt;chart:param name="0" value="#FFFFAA" /&gt;<BR>
* &nbsp;&nbsp;&lt;chart:param name="1" value="#AAFFAA" /&gt;<BR>
* &nbsp;&nbsp;&lt;chart:param name="2" value="#FFAAFF" /&gt;<BR>
* &nbsp;&nbsp;&lt;chart:param name="3" value="#FFAAAA" /&gt;<BR>
* &lt;/chart:chartpostprocessor&gt;
*/

public class SeriesPaintProcessor implements ChartPostProcessor, Serializable {
	static final long serialVersionUID = -2290498142826058256L;

	public void processChart(Object chart, Map params) {
		JFreeChart localChart = (JFreeChart) chart;
		Plot plot = localChart.getPlot();

		if (plot instanceof CombinedDomainXYPlot) {
			processSubChart(((CombinedDomainXYPlot) plot).getSubplots(), params);
		}
		else if (plot instanceof CombinedDomainCategoryPlot) {
			processSubChart(((CombinedDomainCategoryPlot) plot).getSubplots(), params);
		}
		else if (plot instanceof CombinedRangeXYPlot) {
			processSubChart(((CombinedRangeXYPlot) plot).getSubplots(), params);
		}
		else if (plot instanceof CombinedRangeCategoryPlot) {
			processSubChart(((CombinedRangeCategoryPlot) plot).getSubplots(), params);
		}
		// pie charts
		else if (plot instanceof PiePlot) {
			PiePlot piePlot = (PiePlot) plot;

			List keys = piePlot.getDataset().getKeys();
			for (int i = 0; i < params.size(); i++) {
				String colorStr = (String) params.get(String.valueOf(i));
				piePlot.setSectionPaint((Comparable) keys.get(i), Color.decode(colorStr));
			}

			// category plots
		}
		else if (plot instanceof CategoryPlot) {
			CategoryPlot categoryPlot = (CategoryPlot) plot;
			int colorCount = 0;
			for (int i = 0; i < categoryPlot.getRendererCount(); i++) {
				CategoryItemRenderer render = categoryPlot.getRenderer(i);
				for (int j = 0; j < render.getPassCount(); j++) {
					if (colorCount >= params.size()) {
						return;
					}
					String colorStr = (String) params.get(String.valueOf(colorCount++));
					render.setSeriesPaint(j, Color.decode(colorStr));
				}
			}
			// spider web plots
		}
		else if (plot instanceof SpiderWebPlot) {
			SpiderWebPlot swPlot = (SpiderWebPlot) plot;

			for (int i = 0; i < params.size(); i++) {
				String colorStr = (String) params.get(String.valueOf(i));
				swPlot.setSeriesPaint(i, Color.decode(colorStr));
			}

			// XY plots
		}
		else if (plot instanceof XYPlot) {
			XYPlot xyPlot = (XYPlot) plot;
			int colorCount = 0;
			for (int i = 0; i < xyPlot.getRendererCount(); i++) {
				XYItemRenderer render = xyPlot.getRenderer(i);
				for (int j = 0; j < render.getPassCount(); j++) {
					if (colorCount >= params.size()) {
						return;
					}
					String colorStr = (String) params.get(String.valueOf(colorCount++));
					render.setSeriesPaint(j, Color.decode(colorStr));
				}
			}

			// Wafer Map plots
		}
		else if (plot instanceof WaferMapPlot) {
			WaferMapRenderer render = ((WaferMapPlot) plot).getRenderer();

			for (int i = 0; i < params.size(); i++) {
				String colorStr = (String) params.get(String.valueOf(i));
				render.setSeriesPaint(i, Color.decode(colorStr));
			}
		}
	}

	private void processSubChart(List<Plot> plots, Map params) {
		int colorCount = 0;
		for (Plot plot : plots) {
			if (plot instanceof XYPlot) {
				XYItemRenderer render = ((XYPlot) plot).getRenderer();
				for (int i = 0; i < render.getPassCount(); i++) {
					if (colorCount >= params.size()) {
						return;
					}
					String colorStr = (String) params.get(String.valueOf(colorCount++));
					render.setSeriesPaint(i, Color.decode(colorStr));
				}
			}
			else if (plot instanceof CategoryPlot) {
				CategoryItemRenderer render = ((CategoryPlot) plot).getRenderer();
				for (int i = 0; i < render.getPassCount(); i++) {
					if (colorCount >= params.size()) {
						return;
					}
					String colorStr = (String) params.get(String.valueOf(colorCount++));
					render.setSeriesPaint(i, Color.decode(colorStr));
				}
			}
		}
	}
}
